import 'package:flutter/services.dart';

/// 输入框常用格式化封装
class TextInputFormatUtils {
  /// 小数，默认：整数9位，小数4位
  static List<TextInputFormatter> decimal(
      {integerLength = 9, decimalLength = 4, bool signed = false}) {
    return [
      FilteringTextInputFormatter.allow(
          signed ? RegExp(r'[0-9.-]') : RegExp(r'[0-9.]')),
      FilteringTextInputFormatter.deny(
        RegExp(r'^\.+'), //不能小数点开头
      ),
      NumLengthInputFormatter(
          integerLength: integerLength, decimalLength: decimalLength)
    ];
  }

  /// 手机号码
  /// [onlyChina] 是否仅支持国内
  static List<TextInputFormatter> phone({bool onlyChina = false}) {
    if (onlyChina) {
      return [
        FilteringTextInputFormatter.allow(RegExp("[0-9]")),
        NumLengthInputFormatter(integerLength: 11)
      ];
    }
    return [
      FilteringTextInputFormatter.allow(RegExp("[0-9.+-\\s]")),
    ];
  }

  /// 正整数：默认9位
  static List<TextInputFormatter> integer({integerLength = 9}) {
    return [
      FilteringTextInputFormatter.allow(RegExp("[0-9]")),
      NumLengthInputFormatter(integerLength: integerLength)
    ];
  }

  /// 数字，只能【0-9】
  static List<TextInputFormatter> numbers() {
    return [
      FilteringTextInputFormatter.allow(RegExp("[0-9]")),
    ];
  }

  /// 不允许输入某写字符
  static List<TextInputFormatter> deny(String regExp) {
    return [
      FilteringTextInputFormatter.deny(RegExp(regExp)),
    ];
  }

  /// 只允许输入某写字符
  static List<TextInputFormatter> allow(String regExp) {
    return [
      FilteringTextInputFormatter.allow(RegExp(regExp)),
    ];
  }

  /// 只允许整数的最大值（支持最小值）
  static List<TextInputFormatter> maxInter(int max,
      {int? min,
      bool? isContainLower,
      bool? isContainUpper,
      int? decimalPlaces}) {
    return [
      FilteringTextInputFormatter.allow(RegExp("[0-9]")),
      NumberInputLimit(
          max: max.toDouble(),
          min: min?.toDouble(),
          isContainLower: isContainLower,
          isContainUpper: isContainUpper,
          decimalPlaces: decimalPlaces),
    ];
  }

  /// 只允许的最大值（支持最小值）
  static List<TextInputFormatter> limitMinAndMax(double max,
      {double? min,
      bool? isContainLower,
      bool? isContainUpper,
      int? decimalPlaces}) {
    return [
      FilteringTextInputFormatter.allow(RegExp("[0-9.]")),
      NumberInputLimit(
          max: max,
          min: min ?? 0,
          isContainLower: isContainLower,
          isContainUpper: isContainUpper,
          isInteger: false,
          decimalPlaces: decimalPlaces),
    ];
  }
}

/// 整数和小数位限制
class NumLengthInputFormatter extends TextInputFormatter {
  int decimalLength;
  int integerLength;

  NumLengthInputFormatter({this.integerLength = 9, this.decimalLength = 4})
      : super();

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    String value = newValue.text;
    int selectionIndex = newValue.selection.end;

    int firstDecIndex = newValue.text.indexOf('-');
    int lastDecIndex = newValue.text.lastIndexOf('-');
    if (firstDecIndex != lastDecIndex &&
        newValue.text.length > oldValue.text.length) {
      value = oldValue.text;
      selectionIndex = oldValue.selection.end;
    } else {
      if (newValue.text.contains('.')) {
        int pointIndex = newValue.text.indexOf('.');
        int lastPointIndex = newValue.text.lastIndexOf('.');
        if (pointIndex == lastPointIndex) {
          String beforePoint =
              newValue.text.substring(0, pointIndex).replaceAll('-', '');
          //小数点前内容大于integerLength
          if (beforePoint.length > integerLength) {
            if (newValue.text.length > oldValue.text.length) {
              value = oldValue.text;
              selectionIndex = oldValue.selection.end;
            }
          } else
          //小数点前内容小于等于integerLength
          {
            String afterPoint =
                newValue.text.substring(pointIndex + 1, newValue.text.length);
            if (afterPoint.length > decimalLength) {
              int oldIndex = oldValue.text.indexOf('.');
              String oldAfterPoint =
                  oldValue.text.substring(oldIndex + 1, oldValue.text.length);
              if (oldAfterPoint.length < afterPoint.length) {
                //已经超了再输入小数，不让输入
                value = oldValue.text;
                selectionIndex = oldValue.selection.end;
              }
            } else {
              //0开头的整数
              if (beforePoint.startsWith('0') && beforePoint.length > 1) {
                value = newValue.text.substring(1);
                selectionIndex = selectionIndex - 1;
              }
            }
          }
        } else {
          //多个小数点的情况，不让输入
          value = oldValue.text;
          selectionIndex = oldValue.selection.end;
        }
      } else {
        var newText = newValue.text.replaceAll('-', '');
        if (newText.length > integerLength) {
          var oldText = oldValue.text.replaceAll("-", '');
          if (newText.length > oldText.length) {
            value = oldValue.text;
            selectionIndex = oldValue.selection.end;
          }
        } else {
          //0开头的整数
          if (newText.startsWith('0') && newText.length > 1) {
            if (newValue.text.startsWith('-')) {
              value = '-${newText.substring(1)}';
              selectionIndex = selectionIndex - 1;
            } else {
              value = newText.substring(1);
              selectionIndex = selectionIndex - 1;
            }
          }
        }
      }
    }
    return TextEditingValue(
      text: value,
      selection: TextSelection.collapsed(offset: selectionIndex),
    );
  }
}

class NumberInputLimit extends TextInputFormatter {
  ///允许的最大值,
  final double max;

  ///允许的最小值，默认不限制
  final double? min;

  ///是否只允许输入的值为整数
  final bool isInteger;

  /// 是否包含最小值
  final bool? isContainLower;

  /// 是否包含最大值
  final bool? isContainUpper;

  /// 保留几位小数
  final int? decimalPlaces;

  NumberInputLimit(
      {required this.max,
      this.min,
      this.isInteger = true,
      this.isContainLower,
      this.isContainUpper,
      this.decimalPlaces});

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    //最新文本
    String newContent = newValue.text;
    double? newDouble = double.tryParse(newContent);
    if (newDouble != null) {
      if (newDouble >= max) {
        String newContent = max.toString();
        if (isInteger) {
          int maxContent = max.truncate();
          newContent = maxContent.toString();
        }

        /// 初始参数和展会历史参数，恶心的处理
        if (isContainUpper != null) {
          double resultMax = double.parse(newContent);
          if (resultMax == max && !isContainUpper!) {
            resultMax = resultMax * 0.999;
            if (decimalPlaces != null) {
              double formattedValue =
                  double.parse(resultMax.toStringAsFixed(decimalPlaces!));
              if (formattedValue == 0) {
                formattedValue = 1;
                int dp = decimalPlaces! + 1;
                for (var i = 0; i < dp; i++) {
                  formattedValue = formattedValue * 0.1;
                }
              }
              resultMax = formattedValue;
            }
            newContent = resultMax.toString();
          }
        }
        return TextEditingValue(
          text: newContent,
          selection: TextSelection.collapsed(offset: newContent.length),
        );
      } else if (min != null && newDouble < min!) {
        String newContent = min!.toString();
        if (isInteger) {
          int minContent = min!.truncate();
          newContent = minContent.toString();
        }

        /// 初始参数和展会历史参数，恶心的处理
        if (isContainLower != null) {
          double resultMax = double.parse(newContent);
          if (resultMax == min && !isContainLower!) {
            resultMax = resultMax * 0.001;
            if (decimalPlaces != null) {
              double formattedValue =
                  double.parse(resultMax.toStringAsFixed(decimalPlaces!));
              if (formattedValue == 0) {
                formattedValue = 1;
                int dp = decimalPlaces! + 1;
                for (var i = 0; i < dp; i++) {
                  formattedValue = formattedValue * 0.1;
                }
              }
              resultMax = formattedValue;
            }
            newContent = resultMax.toString();
          }
        }
        return TextEditingValue(
          text: newContent,
          selection: TextSelection.collapsed(offset: newContent.length),
        );
      }
    }
    return newValue;
  }
}
